package com.jiukuaidao.library.base;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.jiukuaidao.library.R;
import com.jiukuaidao.library.common.dialog.CommDialog;
import com.jiukuaidao.library.common.dialog.ICallBack;
import com.jiukuaidao.library.common.dialog.LoadingDialog;
import com.jiukuaidao.library.common.page.VaryViewHelperController;
import com.jiukuaidao.library.util.NetUtils;
import com.jiukuaidao.library.util.ToastUtil;

import java.lang.reflect.Field;

import butterknife.ButterKnife;


/**
 * Author : BinarySatan
 */
public abstract class BaseFragment<T> extends Fragment implements IBaseView<T> {

    private Context mContext;
    private boolean mIsPrepard;

    private boolean isCurrent = false;

    private VaryViewHelperController mVaryViewHelperController;

    protected View mView;

    protected T mPresenter;

    protected LoadingDialog mLoadingDialog;

    public BaseFragment() {

    }

    /**
     * @param clazz
     * @param <F>
     * @return
     */
    public static <F extends BaseFragment> F newInstance(Class<F> clazz) {
        return newInstance(clazz, null);
    }

    /**
     * @param clazz
     * @param bundle
     * @param <F>
     * @return
     */
    public static <F extends BaseFragment> F newInstance(Class<F> clazz, Bundle bundle) {
        F fragment = null;
        try {
            fragment = clazz.newInstance();
            fragment.setArguments(bundle);
        } catch (java.lang.InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return fragment;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (getContentLayoutId() != 0) {
            mView = inflater.inflate(getContentLayoutId(), container, false);
        } else {
            mView = super.onCreateView(inflater, container, savedInstanceState);
        }
        return mView;
    }

    /**
     * 实现先登录再跳转
     *
     * @param isLogin
     * @param toClazz
     * @param fromClass
     * @param loginActivity
     */
    public void startLoginJump(boolean isLogin, Class toClazz, Class fromClass, Class loginActivity, Bundle toActivityBundle) {
        if (!isLogin) {
            if (toClazz == fromClass) {// 登录后返回需要刷新
                intentJumpForResult(loginActivity, 0);
            } else if (toClazz == null) {// 登录后返回无需刷新
                intentJump(loginActivity);
            } else {// 登录后跳转至目标activity
                Bundle b = new Bundle();
                b.putString("toActivity", toClazz.getName());
                b.putBundle("toActivityBundle", toActivityBundle);
                intentJump(loginActivity, b);
            }
        } else {
            if (toClazz != fromClass) {
                intentJump(toClazz, toActivityBundle);
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (getTargetView() == null)
            return;

        mVaryViewHelperController = new VaryViewHelperController(getTargetView());
    }

    @Override
    public void setPresenter(T presenter) {
        mPresenter = presenter;
    }

    @Override
    public void showDialogOneBtn(String msg, ICallBack.OneCallBack callBack) {
        showDialogOneBtn(msg, null, callBack);
    }

    @Override
    public void showDialogOneBtn(String msg, String confirmStr, ICallBack.OneCallBack callBack) {
        CommDialog dialog = new CommDialog(getActivity().getParent());
        dialog.setCallback(callBack);
        dialog.show(msg, confirmStr);
    }

    @Override
    public void showDialogTwoBtn(String msg, ICallBack.TwoCallBack callBack) {
        showDialogTwoBtn(msg, null, null, callBack);
    }

    @Override
    public void showDialogTwoBtn(String msg, String leftStr, String rightStr, ICallBack.TwoCallBack callBack) {
        CommDialog dialog = new CommDialog(getActivity().getParent());
        dialog.setCallback(callBack);
        dialog.show(msg, leftStr, rightStr);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mIsPrepard = true;
        ButterKnife.bind(this, mView);
        bindMVP();
        Bundle bundle = getArguments();
        handleBundle(bundle);
        init();
        if (getUserVisibleHint()) {
            isCurrent = true;
            onUserVisible();
        }
    }

    /**
     * 执行MVP的绑定逻辑
     */
    protected void bindMVP() {
    }

    /**
     * fragment在内存中创建并已加载布局文件，但还不可见，可进行联网等初始化操作
     */
    protected abstract void init();

    @Override
    public void onDestroy() {
        super.onDestroy();

        try {
            Field childFragmentManager = android.support.v4.app.Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mIsPrepard = false;
    }

    @Override
    public void onResume() {// Fragment的onResumt其实就是getActivity()的onResume
        super.onResume();
        if (isCurrent) {
            onUserVisible();
        }
    }

    @Override
    public void onPause() {// Fragment的onPause其实就是getActivity()的onPause
        super.onPause();
        if (isCurrent) {
            onUserInvisible();
        }
    }


    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {// 只能监控同级Fragment互相切换时的显隐
        super.setUserVisibleHint(isVisibleToUser);
        if (mIsPrepard) {
            if (isVisibleToUser) {// 可见
                isCurrent = true;
                onUserVisible();
            } else {// 不可见
                isCurrent = false;
                onUserInvisible();
            }
        }
    }

    protected abstract View getTargetView();

    /**
     * fragment 可见
     */
    protected abstract void onUserVisible();

    /**
     * fragment不可见
     */
    protected abstract void onUserInvisible();

    /**
     * 处理开启Fragment时传入的参数
     *
     * @param bundle
     */
    protected void handleBundle(Bundle bundle) {

    }


    @Override
    public void showLoading(String msg) {
        mLoadingDialog = new LoadingDialog(getActivity());
        mLoadingDialog.show(msg);
    }

    @Override
    public void hideLoading() {
        if (mLoadingDialog != null)
            mLoadingDialog.dismiss();
    }

    @Override
    public void showEmpty(String emptyMsg) {
        mVaryViewHelperController.showEmpty(emptyMsg, null);
    }

    @Override
    public void showNetworkException(final IBasePresenter presenter) {
        mVaryViewHelperController.showNetworkError(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (NetUtils.isNetworkConnected()) {

                    if (presenter == null)
                        return;

                    presenter.start();
                    mVaryViewHelperController.restore();
                }
            }
        });
    }

    @Override
    public void showError(String errMsg) {
        ToastUtil.show(errMsg, Toast.LENGTH_SHORT);
    }

    protected void intentJump(Class<?> clazz) {
        intentJump(clazz, null);
    }

    protected void intentJump(Class<?> clazz, Bundle bundle) {
        Intent intent = new Intent(mContext, clazz);
        if (bundle != null)
            intent.putExtras(bundle);

        startActivity(intent);
        judgeOverridePendingTransition(true);
    }

    protected void intentJumpForResult(Class<?> clazz, int requestCode) {
        intentJumpForResult(clazz, requestCode, null);
    }

    protected void intentJumpForResult(Class<?> clazz, int requestCode, Bundle bundle) {
        Intent intent = new Intent(mContext, clazz);
        if (bundle != null)
            intent.putExtras(bundle);

        startActivityForResult(intent, requestCode);
    }

    protected abstract int getContentLayoutId();


    private void judgeOverridePendingTransition(boolean isIn) {

        if (isIn) {
            if (getEnterDirection() == 0)
                getActivity().overridePendingTransition(R.anim.right_in, R.anim.left_out);
            else
                switch (getEnterDirection()) {
                    case 1:
                        getActivity().overridePendingTransition(R.anim.right_in, R.anim.left_out);
                        break;
                    case 2:
                        getActivity().overridePendingTransition(R.anim.right_out, R.anim.left_in);
                        break;
                    case 3:
                        getActivity().overridePendingTransition(R.anim.top_out, R.anim.bottom_in);
                        break;
                    case 4:
                        getActivity().overridePendingTransition(R.anim.bottom_out, R.anim.top_in);
                        break;
                }
        } else {
            if (getEnterDirection() == 0)
                getActivity().overridePendingTransition(R.anim.left_in, R.anim.right_out);
            else
                switch (getEnterDirection()) {
                    case 1:
                        getActivity().overridePendingTransition(R.anim.left_out, R.anim.right_in);
                        break;
                    case 2:
                        getActivity().overridePendingTransition(R.anim.right_out, R.anim.left_in);
                        break;
                    case 3:
                        getActivity().overridePendingTransition(R.anim.top_out, R.anim.bottom_in);
                        break;
                    case 4:
                        getActivity().overridePendingTransition(R.anim.bottom_out, R.anim.top_in);
                        break;
                }
        }
    }

    protected int getEnterDirection() {
        return 0;
    }

}
